#!/usr/bin/python3
try:
    import os,sys,time
    import serial
    import serial.tools.list_ports
    import binascii
    import subprocess
    import signal
    import re       # 正则表达式
except ImportError:
    print(">>> lib not found !!!")
    print(">>> Please pip3 install pyserial !")
    exit(1)
    
# 信号超时方法
def handler(signum, frame):
    print("查找EC20模块的串口超时")
    raise Exception("Get ttyUSB Time's out!")
####################################################################################################
class LTE_MOD:
    def __init__(self):
        self.ser=None
        self.init()
        
    def __del__(self):
        self.close_4g_GPS_session()
        self.ser.close()
    
    # 查找EC20模块的串口
    def find_at_port(self):
        ports = serial.tools.list_ports.comports()
        for port in ports:
            # print("ports===============", port.device)
            # 测试是否为AT指令接口
            ser = serial.Serial(port.device, 115200, timeout=1)  # 串口初始化，根据实际情况修改串口号和波特率
            ser.write(b'AT\r\n')  # 发送AT指令
            response = ser.read(128).decode()  # 读取响应
            ser.close()  # 关闭串口
            # print(response)
            if response.find("OK"):
                return port.device
        return None
    
    
    # 初始化4G模块与功能
    def init(self):
        # 判断是否有AT接口    # apt install python3-serial
        mode_at_port = self.find_at_port()
        # mode_at_port = "/dev/ttyUSB3"
        print(">>> 4G模块的AT端口是%s"%mode_at_port)
        
        # 打开AT口
        self.ser = serial.Serial(mode_at_port, 115200,
                            bytesize=serial.EIGHTBITS,  # 数据位：8位
                            parity=serial.PARITY_NONE,  # 校验位：无
                            stopbits=serial.STOPBITS_ONE,  # 停止位：1位
                            timeout=None)  # 读超时时间
        if self.ser.is_open != False:
            print("打开串口成功,串口详情参数：", self.ser)
            self.open_4g_GPS_session()
        else:
            print(">>> %s 串口打开失败！！！"%mode_at_port)
            exit(99)
        
        # 执行拨号程序，拨号程序的输出需要记录(未测试)
        # quectel_CM_addr="/root/rules/quectel-CM/quectel-CM"
        # with open('run.log', 'w') as f:
        #     subprocess.run(['/root/rules/quectel-CM/quectel-CM'], stdout=f, stderr=subprocess.STDOUT)
        
        
    # 发送AT指令接收数据返回的函数
    def send_AT(self,cmd):
        #print("串口对象参数：",tty)
        self.ser.write(cmd.encode())
        data=self.ser.read(1)
        time.sleep(0.1)
        data = (data + self.ser.read(self.ser.inWaiting())).decode()
        return data
    
    # 获取4G信号强度
    # 0 -113dBm or less
    # 1 -111dBm
    # 2...30 -109... -53dBm(2=-109dBm,30=-53dBm)
    # 31 -51dBm or greater
    # 99 未知或无法检测 
    # 100 -116dBm or less
    # 101 -115dBm
    # 102...190 -114...-26dBm
    # 191 -25dBm or greater
    # 199 未知或无法检测
    # 100~199 扩展用于TDSCDMA指示接收信号代码
    def get_4g_Signal_strength(self):
        data = self.send_AT("AT+CSQ\r\n")
        if data.find("OK"):
            data = data.split('\r\n')[1]
            result = re.findall(r":\s*(\d+),", data)
            if result:
                return result[0]
            else:
                return None
        else:
            return None
        
    # 获取4G模块号
    def get_4g_device_ID(self):
        data = self.send_AT("AT+GSN\r\n")
        if data.find("OK"):
            data = data.split('\r\n')[1]
            return data
        else:
            return None
    
    # 获取SIM卡状态
    def get_4g_SIM_state(self):
        data = self.send_AT("AT+CPIN?\r\n")
        if data.find("OK"):
            data = data.split('\r\n')[1]
            data = data[7:]
            return data
        else:
            print("ERR :",data)
            return None
            
    # 获取SIM卡号
    def get_4g_SIM_ID(self):
        if self.get_4g_SIM_state() == "READY":
            data = self.send_AT("AT+QCCID\r\n")
            if data.find("OK"):
                data = data.split('\r\n')[1]
                data = data[8:]
                return data
            else:
                return None
        else:
            print("No SIM !!!")
            return None  

####################################################################################################   
    # 获取GPS状态，1为启动，0为关闭
    def get_4g_GPS_state(self):
        data = self.send_AT("AT+QGPS?\r\n")
        if data.find("OK"):
            data = data.split('\r\n')[1]
            data = data[7:]
            return data
        else:
            return None
        
    # 开启GPS会话
    def open_4g_GPS_session(self):
        
        data = self.send_AT("AT+QGPS=1,1,1,0,1\r\n")
        if data.find("OK"):
            # print("开启GPS会话成功！！！")
            return 0
            
    # 关闭GPS会话    
    def close_4g_GPS_session(self):
        data = self.send_AT("AT+QGPSEND\r\n")
        if data.find("OK"):
            #  print("关闭GPS会话成功！！！")
            return 0
    
    # 获取GPS信息
    # 返回：原始数据
    def get_4g_GPS_raw_data(self):
        data = self.send_AT("AT+QGPSLOC=1\r\n")
        print(data)
        if data.find("OK")== -1:
            return None
        else:
            data = data.split('\r\n')[1]
            data = data[10:]
            return data
    # 获取坐标信息
    def get_4g_GPS_info(self):
        while True:
            raw_gps_data = self.get_4g_GPS_raw_data()
            print(raw_gps_data)
            if raw_gps_data == None:
                # 数据没有正确接收
                continue
            else:
                print(raw_gps_data.split(',')[1],raw_gps_data.split(',')[3])
                # 数据处理
                # 转为度：dd+(mm.mmmm/60)
                latitude_raw=raw_gps_data.split(',')[1] # 纬度
                longitude_raw=raw_gps_data.split(',')[3] # 经度
                
                degrees = int(longitude_raw[:3])
                minutes = float(longitude_raw[3:])
                longitude = degrees + minutes / 60
                
                degrees = int(latitude_raw[:2])
                minutes = float(latitude_raw[2:])
                latitude = degrees + minutes / 60
                return longitude,latitude
            time.sleep(1.5)

    def get_4g_device_state(self):
        pass
####################################################################################################
    

